
`include "alu_defs.v"

`timescale 1ns / 1ps

module tb_alu;

parameter DATA_WIDTH = 32;

reg i_cin;

reg [`ALU_FUNC_WIDTH-1:0] i_func;
reg [DATA_WIDTH-1:0] i_op_a;
reg [DATA_WIDTH-1:0] i_op_b;

wire o_cout;
wire o_zero;
wire o_ovf;
wire o_sign;
wire [DATA_WIDTH-1:0] o_rez;

defparam alu_DUT.DATA_WIDTH = DATA_WIDTH;

alu alu_DUT(
	.i_cin(i_cin),
	.i_func(i_func),
	.i_op_a(i_op_a),
	.i_op_b(i_op_b),		
	.o_cout(o_cout),
	.o_zero(o_zero),
	.o_ovf(o_ovf),
	.o_sign(o_sign),
	.o_rez(o_rez)
);

initial
begin
	init_all_inputs_to_0;
	#10
	set_inputs( 0, `ALU_FUNC_ADD, 10, 20 );
	set_inputs( 0, `ALU_FUNC_SUBA, 10, 20 );
	set_inputs( 0, `ALU_FUNC_SUBB, 10, 20 );
	set_inputs( 0, `ALU_FUNC_ADD, 32'hFFFFFFFF, 1 );
	set_inputs( 0, `ALU_FUNC_ADD, 32'h7FFFFFFF, 1 );	
	set_inputs( 0, `ALU_FUNC_OR, 5, 0 );
	set_inputs( 0, `ALU_FUNC_AND, 5, 7 );
	set_inputs( 0, `ALU_FUNC_EXOR, 5, 7 );
	set_inputs( 0, `ALU_FUNC_EXNOR, 5, 7 );
	#10
	$finish;
end

task init_all_inputs_to_0;
begin
	i_cin = 0;
	i_func = 0;
	i_op_a = 0;
	i_op_b = 0;
end
endtask

task set_inputs;
	input cin;
	input [`ALU_FUNC_WIDTH-1:0] func;
	input [DATA_WIDTH-1:0] a;
	input [DATA_WIDTH-1:0] b;
begin
		i_cin = cin;
		i_func = func;
		i_op_a = a;
		i_op_b = b;
	#10 ;
		// wait for time to pass and watch the results on waveforms
end

endtask

endmodule
